<?php
namespace yii\base;

/**
 * Behavior 类是所有行为类的基类
 *
 * 行为可被用来扩展已存在的组件的功能而不需要修改其代码
 * 特别的是，它可以将自己的属性和方法注入到组件中
 * 这些方法和属性可通过组件直接访问. 它还可以响应组件中触发的事件
 * 
 * 从而拦截正常的代码执行。
 */
class Behavior extends Object
{
    /**
     * @var Component 行为的附加对象
     */
    public $owner;


    /**
     * 申明 [[owner]] 的事件的处理程序
     * 子类可以重写此方法以声明应将哪些PHP回调附加到[[owner]]组件的事件。
     * 当行为附加到所有者时，事件的处理程序将附加到[[所有者]]的事件; 当行为与组件分离时，它们将与事件分离。
     * 事件的处理程序可以是以下任何一种：
     *
     * - 行为类中的方法    : `'handleClick'`, equivalent to `[$this, 'handleClick']`
     * - 对象方法       : `[$object, 'handleClick']`
     * - 静态方法       : `['Page', 'handleClick']`
     * - 匿名函数       : `function ($event) { ... }`
     *
     * 例如：
     *
     * ```php
     * [
     *     Model::EVENT_BEFORE_VALIDATE => 'myBeforeValidate',
     *     Model::EVENT_AFTER_VALIDATE => 'myAfterValidate',
     * ]
     * ```
     *
     * @return array 事件（数组的键键）和相应的事件处理程序（数组的值）。
     */
    public function events()
    {
        return [];
    }

    /**
     * 将行为对象附加到组件。
     * 默认实现将设置行为对象的[[owner]]属性, 并为其附加[[events]]中声明的事件处理程序。
     * 如果重写此方法，请确保调用父实现。
     * @param Component $owner 被附加行为的对象.
     */
    public function attach($owner)
    {
        $this->owner = $owner;
        foreach ($this->events() as $event => $handler) {
            $owner->on($event, is_string($handler) ? [$this, $handler] : $handler);
        }
    }

    /**
     * 从组件中分离行为对象。
     * 默认实现将释放[[owner]]属性, 并分离在[[events]]中声明的事件处理程序。 
     * 如果重写此方法，请确保调用父实现。
     */
    public function detach()
    {
        if ($this->owner) {
            foreach ($this->events() as $event => $handler) {
                $this->owner->off($event, is_string($handler) ? [$this, $handler] : $handler);
            }
            $this->owner = null;
        }
    }
}
